package bilby;


import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
import java.util.stream.Collectors;

/**
 * 保存袋狸
 * ①初始化地区物种，设定均为可繁殖的物种
 * ②设定
 *
 * @author Tght
 * @date 2022/10/20
 */
public class SaveTheBilby {
    /**
     * 每个地区的初始物种信息
     */
    public static Location[] arrLocation = new Location[10];
    public static Location[] arrLocationStart = new Location[10];

    /**
     * 统计每月物种数据  [['10,2,3','2,3,1',...],['10,2,3','2,3,1',...],...]
     * 用一个二维数组记录每个区域每个月的10个地区的历史活物种情况
     */
    public static String[][] historyRecordAlive = new String[12][10];
    /**
     * 每个月每个地区，到当月的死亡累计
     */
    public static String[][] historyRecordDead = new String[12][10];
    public static String[][] historyRecordNewBorn = new String[12][10];

    public static Integer months = 0;

    /**
     * 不符合的状态，则遍历请求迁移
     */
    public static int status = 0;
    /**
     * 种群干预措施
     */
    public static Integer numberOfPopulationInterventions = 1;


    public static void main(String[] args) {
        startSave();
        SaveTheBilby theBilby = new SaveTheBilby();
        theBilby.init();
    }

    public static void startSave() {
        // 1.给每个地区分配好对应的物种
        arrLocation = BornAt.initCreateBaby();
        // 2.记录最初的数组信息
        arrLocationStart = BornAt.initCreateBaby();
    }

    public void init() {
        // 1.欢迎信息
        welcome();
        // 2.进入月循环
        monthlyCycle();
        // 3.进入年总结
        yearCycle();
    }

    public void welcome(){
        System.out.println("欢迎来到兔耳袋狸模拟");
        System.out.print("请输入你将要模拟的地区名称: ");
        Scanner sc = new Scanner(System.in);
        String next = "";
        while (true) {
            next = sc.next();
            if (next.length() <= 16) {
                break;
            }
            System.out.println("地区名最长不超过16个字符哦");
            System.out.print("请再次输入: ");
        }
        System.out.println("开始" + next + "兔耳袋狸生存模拟，生成地区数据中...");
    }

    /**
     * 月周期
     */
    public void monthlyCycle() {
        Scanner sc = new Scanner(System.in);
        while (months < 12) {
            RegionalTraversal();
            // 月概率事件结束，根据研究员的报告进入下个月份
            if (months != 11) {
                // 邀请研究员互动
                inputKill(sc);
            }else {
                System.out.println("研究结束");
            }

            months++;
        }
    }

    /**
     * 邀请研究员互动
     *
     * @param sc sc
     */
    public void inputKill(Scanner sc) {

        ArrayList<Location> locations = getBilyNumByStaticArrLocation();

        StringBuilder builder = new StringBuilder();
        for (Location x : locations) {
            builder.append(x.getName()).append(" ");
        }

        if (locations.isEmpty()) {
            if (status == 1) {
                status = 0;
                return;
            }
            System.out.println(months + 1 + "月地区族群数量未超出限制,暂不需要迁移,可选屠魔令:  Y:启动屠魔令 N:不启用屠魔令 ");
        } else {
            System.out.println(months + 1 + "月," + builder.toString() + "地区族群数量超出限制，建议主动迁移，也可选屠魔令: A:迁移 B:屠魔令 Q:不操作地区 E:不操作");
            status = 1;
        }
        String next = sc.next();
        int i = 0;
        if ("A".equals(next) || "B".equals(next) || "Q".equals(next) || "Y".equals(next)) {
            if (("B".equals(next) || "Y".equals(next)) && numberOfPopulationInterventions == 1) {
                numberOfPopulationInterventions--;
            } else if (("B".equals(next) || "Y".equals(next)) && numberOfPopulationInterventions != 1) {
                System.out.println("请善待小动物");
                inputKill(sc);
                return;
            }
            System.out.println("请选择操作地区,输入 (1-10)");
            i = sc.nextInt();
        }
        if ("E".equals(next)){
            // for循环处理多出的兔耳袋狸
            String[] s = builder.toString().split(" ");
            for (int j = 0; j < s.length; j++) {
                // 发生信息交互
                input("Q", Integer.parseInt(s[j]));
            }
        }else {
            // 发生信息交互
            input(next, i);
        }

        if (status == 1) {
            inputKill(sc);
        }
    }

    /**
     * input交互
     */
    public void input(String next, int i) {
        switch (next) {
            case "Y":
            case "B":
                // 屠魔令
                killing(arrLocation[i - 1]);
                break;
            case "A":
                // 迁徙
                migration(arrLocation[i - 1], true);
                break;
            case "Q":
                // 死亡
                migration(arrLocation[i - 1], false);
                break;
            case "N":
                // 不用屠魔令
        }
    }


    /**
     * 拿到arrLocation中兔耳袋狸的数量
     */
    public ArrayList<Location> getBilyNumByStaticArrLocation() {
        Location[] locations = arrLocation;
        //获取需要干预的地区
        ArrayList<Location> list = new ArrayList<>();
        for (int i = 0; i < locations.length; i++) {
            List<Bilby> collect = locations[i].getBilbyArrayList().stream().filter(s -> s.isAliveStatus() == true).collect(Collectors.toList());
            if (collect.size() > 20) {
                list.add(locations[i]);
            }
        }
        return list;
    }


    /**
     * 区域遍历
     */
    public void RegionalTraversal() {
        for (int i = 0; i < arrLocation.length; i++) {
            // 去单独的这个区域那数据
            Location zone = singleZone(i);

            // 更新这个月，这个区域的数据
            arrLocation[i] = zone;
            // 计算当月各区域 活 的物种数量
            int i1 = zone.getBilbyArrayList().stream().filter(s -> s.isAliveStatus() == true).collect(Collectors.toList()).size();
            int i2 = zone.getFoxArrayList().stream().filter(s -> s.isAliveStatus() == true).collect(Collectors.toList()).size();
            int i3 = zone.getCatArrayList().stream().filter(s -> s.isAliveStatus() == true).collect(Collectors.toList()).size();
            historyRecordAlive[months][i] = i1 + "," + i2 + "," + i3 + ",";

            // 计算当月各区域 死 的物种数量
            int d1 = zone.getBilbyArrayList().stream().filter(s -> s.isAliveStatus() == false).collect(Collectors.toList()).size();
            int d2 = zone.getFoxArrayList().stream().filter(s -> s.isAliveStatus() == false).collect(Collectors.toList()).size();
            int d3 = zone.getCatArrayList().stream().filter(s -> s.isAliveStatus() == false).collect(Collectors.toList()).size();
            historyRecordDead[months][i] = d1 + "," + d2 + "," + d3 + ",";


            int n1 = zone.getBilbyArrayList().stream().filter(s -> s.isNewBorn() == true).collect(Collectors.toList()).size();
            int n2 = zone.getFoxArrayList().stream().filter(s -> s.isNewBorn() == true).collect(Collectors.toList()).size();
            int n3 = zone.getCatArrayList().stream().filter(s -> s.isNewBorn() == true).collect(Collectors.toList()).size();
            historyRecordNewBorn[months][i] = n1 + "," + n2 + "," + n3 + ",";

            Newborn.showDetailNum(months, zone, "month", arrLocation, historyRecordDead);
        }
    }

    /**
     * 单个区域
     */
    public Location singleZone(int i) {
        Location location = arrLocation[i];
        // 循环调用月自动事件
        return randomEvent(location);
    }

    /**
     * 随机顺序执行月事件
     *
     * @param location 位置
     * @return {@link Location}
     */
    public Location randomEvent(Location location) {

        Location locationTemp = location;

        int c1 = 0, c2 = 0, c3 = 0, c4 = 0, c5 = 0;
        while (c1 == 0 || c2 == 0 || c3 == 0 || c4 == 0 || c5 == 0) {
            Random random = new Random();
            // [0,99] = [0,100)
            int nextInt = random.nextInt(100);

            if (0 <= nextInt && nextInt < 20 && c1 == 0) {
                locationTemp = Newborn.createNewBilbyByMonth(locationTemp);
                c1 = 1;
            } else if (20 <= nextInt && nextInt < 40 && c2 == 0) {
                locationTemp = Newborn.createNewCatByMonth(locationTemp);
                c2 = 1;
            } else if (40 <= nextInt && nextInt < 60 && c3 == 0) {
                locationTemp = Newborn.createNewFoxByMonth(locationTemp);
                c3 = 1;
            } else if (60 <= nextInt && nextInt < 80 && c4 == 0) {
                locationTemp = Newborn.foxBehaviorByMonth(locationTemp);
                c4 = 1;
            } else if (80 <= nextInt && nextInt < 100 && c5 == 0) {
                locationTemp = Newborn.catBehaviorByMonth(locationTemp);
                c5 = 1;
            }
        }
        return locationTemp;
    }

    /**
     * 迁徙操作
     */
    public void migration(Location location, Boolean isLiveOrDead) {
        arrLocation = Newborn.interventionOneMigration(location, isLiveOrDead, arrLocation);
    }

    /**
     * 屠魔令
     */
    public void killing(Location location) {
        Location enemy = Newborn.updateEnemy(location);
        int i = Integer.parseInt(location.getName());
        arrLocation[i - 1] = enemy;
    }


    /**
     * yearCycle
     */
    public void yearCycle() {
        System.out.println("=========年终总结=========");
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < arrLocation.length; i++) {
            Location location = arrLocation[i];
            // 1.数量打印
            Newborn.showDetailNum(months, location, "year", arrLocationStart, historyRecordDead);

            // 5.信息保存写入文件
            builder.append(textOutPut(location)).append("\n");

        }
        textWrite(builder.toString());
        // 2.袋狸数量变化
        System.out.println("袋狸数量变化: " + getSumChangeBilby());
        // 3.袋狸稳定因子
        System.out.println("袋狸稳定因子: " + factorBilby());
        // 4.捕食者数量变化
        System.out.println("捕食者数量变化: " + predatorChange());

    }

    public static String textOutPut(Location location) {
        // 区域总数 (生的和死的一起的数量)
        List<Cat> cats = location.getCatArrayList();
        List<Fox> foxes = location.getFoxArrayList();
        List<Bilby> bilbies = location.getBilbyArrayList();
        // 存活的
        List<Cat> cats1 = cats.stream().filter(s -> s.isAliveStatus() == true).collect(Collectors.toList());
        List<Fox> foxes1 = foxes.stream().filter(s -> s.isAliveStatus() == true).collect(Collectors.toList());
        List<Bilby> bilbies1 = bilbies.stream().filter(s -> s.isAliveStatus() == true).collect(Collectors.toList());
        int size1 = cats1.size();
        int size2 = foxes1.size();
        int size3 = bilbies1.size();

        Location res = arrLocationStart[Integer.parseInt(location.getName()) - 1];
        // 该地区初始生死总数
        List<Cat> cats4 = res.getCatArrayList();
        List<Fox> foxes4 = res.getFoxArrayList();
        List<Bilby> bilbies4 = res.getBilbyArrayList();

        int newBorn1C = 0;
        int newBorn2C = 0;
        int newBorn3C = 0;

        for (int i = 0; i < 12; i++) {

            String sNew = historyRecordNewBorn[i][Integer.parseInt(location.getName()) - 1];
            String[] split1 = sNew.split(",");
            newBorn1C += Integer.parseInt(split1[2]);
            newBorn2C += Integer.parseInt(split1[1]);
            newBorn3C += Integer.parseInt(split1[0]);
        }

        // = 出生的 - 现有的 + 原来的
        int dead1 = newBorn1C - size1 + cats4.size();
        int dead2 = newBorn2C - size2 + foxes4.size();
        int dead3 = newBorn3C - size3 + bilbies4.size();


//        List<Cat> cats = location.getCatArrayList();
//        List<Fox> foxes = location.getFoxArrayList();
//        List<Bilby> bilbies = location.getBilbyArrayList();
//
//        // 存活的
//        List<Cat> cats1 = cats.stream().filter(s -> s.isAliveStatus() == true).collect(Collectors.toList());
//        List<Fox> foxes1 = foxes.stream().filter(s -> s.isAliveStatus() == true).collect(Collectors.toList());
//        List<Bilby> bilbies1 = bilbies.stream().filter(s -> s.isAliveStatus() == true).collect(Collectors.toList());
//        int size1 = cats1.size();
//        int size2 = foxes1.size();
//        int size3 = bilbies1.size();
//
//
//        // 死亡的
//        List<Cat> cats3 = cats.stream().filter(s -> s.isAliveStatus() == false).collect(Collectors.toList());
//        List<Fox> foxes3 = foxes.stream().filter(s -> s.isAliveStatus() == false).collect(Collectors.toList());
//        List<Bilby> bilbies3 = bilbies.stream().filter(s -> s.isAliveStatus() == false).collect(Collectors.toList());
//
//        int dead1 = cats3.size();
//        int dead2 = foxes3.size();
//        int dead3 = bilbies3.size();

        String content = size3 + "," + dead3 + "," + size2 + "," + dead2 + "," + size1 + "," + dead1 + ",";
        return content;
    }


    public static float predatorChange() {
        return (getTotalPredatorStart() - getTotalPredatorEnd()) * 100 / (float) getTotalPredatorStart();
    }


    /**
     * 获取狐狸和猫的总数 开始
     */

    public static int getTotalPredatorStart() {
        int size = 0;
        for (int i = 0; i < arrLocationStart.length; i++) {
            Location location = arrLocationStart[i];
            size += location.getCatArrayList().stream().filter(s -> s.isAliveStatus() == true).collect(Collectors.toList()).size();
            size += location.getFoxArrayList().stream().filter(s -> s.isAliveStatus() == true).collect(Collectors.toList()).size();
        }
        return size;
    }


    /**
     * 获取狐狸和猫的总数  结束
     */
    public static int getTotalPredatorEnd() {
        int size = 0;
        for (int i = 0; i < arrLocation.length; i++) {
            Location location = arrLocation[i];
            size += location.getCatArrayList().stream().filter(s -> s.isAliveStatus() == true).collect(Collectors.toList()).size();
            size += location.getFoxArrayList().stream().filter(s -> s.isAliveStatus() == true).collect(Collectors.toList()).size();
        }
        return size;
    }


    /**
     * 袋狸稳定因子
     *
     * @return int
     */
    public static float factorBilby() {
        return (getTotalBirthsBilby() + getTotalDeathsBilby()) / (float) getSumBilbyPopulationStart();
    }


    /**
     * 得到总出生袋狸
     *
     * @return int
     */
    public static int getTotalBirthsBilby() {
        return getSumBilbyPopulationEnd() - getSumBilbyPopulationStart();
    }

    /**
     * 袋狸总死亡数
     *
     * @return int
     */
    public static int getTotalDeathsBilby() {
        int sum = 0;
        for (int i = 0; i < arrLocation.length; i++) {
            Location location = arrLocation[i];
            List<Bilby> collect = location.getBilbyArrayList().stream().filter(s -> s.isAliveStatus() == false).collect(Collectors.toList());
            int deadSize = collect.size();
            sum += deadSize;
        }
        return sum;
    }


    /**
     * 袋狸数量变化
     *
     * @return int
     */
    public static float getSumChangeBilby() {
        return (getSumBilbyPopulationEnd() - getSumBilbyPopulationStart()) * 100f / (float) getSumBilbyPopulationStart();
    }

    public static int getSumBilbyPopulationEnd() {
        int sum = 0;
        for (int i = 0; i < arrLocation.length; i++) {
            Location location = arrLocation[i];
            int size = location.getBilbyArrayList().size();
            sum += size;
        }
        return sum;
    }


    public static int getSumBilbyPopulationStart() {
        int sum = 0;
        for (int i = 0; i < arrLocationStart.length; i++) {
            Location location = arrLocationStart[i];
            int size = location.getBilbyArrayList().size();
            sum += size;
        }
        return sum;
    }

    /**
     * 写入文件
     */
    public static void textWrite(String content) {
        String pathEnd = BornAt.pathEnd;
        File file = new File(pathEnd);
        FileWriter fr = null;
        try {
            fr = new FileWriter(file);
            fr.write(content);
            System.out.println("保存信息完成！");
        } catch (IOException e) {
            System.out.println("哎呀，遇到问题了");
            e.printStackTrace();
        } finally {
            try {
                fr.close();
            } catch (IOException e) {
                System.out.println("哎呀，关闭流遇到问题了");
                e.printStackTrace();
            }
        }

    }
}
